package logic

import (
	"errors"
	"fmt"
	"github.com/baker-yuan-connect/botgo/dto"
	"github.com/go-redis/redis"
	"log"
	"time"
)



func GetRedis() *redis.Client {
	return redis.NewClient(&redis.Options{
		Addr:     dto.RedisAddr,
		Password: dto.RedisPassword,
	})
}

// SignByRedis 签到功能Redis位图实现
type SignByRedis struct {
}

// DoSign 当日签到
// SETBIT botgo:u:sign:{uid}:{yyyyMM} {dd-1} 1
func (sign SignByRedis) DoSign(uid string) (bool, error) {
	log.Println("SignByRedis Sign")
	// 计算offset
	var offset int = time.Now().Local().Day() - 1
	var key string = buildSignKey(uid)
	redisApi := GetRedis()
	if v, _ := redisApi.GetBit(key, int64(offset)).Result(); v == 1 {
		return false, errors.New("今日以签到")
	}
	_, err := redisApi.SetBit(key, int64(offset), 1).Result()
	if err != nil {
		return false, err
	}
	log.Println(fmt.Printf("SignByRedis DoSign success offset=%d,key=%s", offset, key))
	defer redisApi.Close()
	return true, nil
}

// CompensateSign 补签
// SETBIT botgo:u:sign:{uid}:{yyyyMM} {offset} 1
func (c SignByRedis) CompensateSign(uid string, offset int) (bool, error) {
	log.Println(fmt.Printf("CompensateSign uid=%s,offset=%d", uid, offset))
	var key string = buildSignKey(uid)
	redisApi := GetRedis()
	if v, _ := redisApi.GetBit(key, int64(offset)).Result(); v == 1 {
		log.Println(fmt.Printf("重复补签 uid=%s,offset=%d", uid, offset))
		return false, errors.New("以签到，请勿重复补签")
	}
	_, err := redisApi.SetBit(key, int64(offset), 1).Result()
	if err != nil {
		log.Println(fmt.Printf("SetBit 异常 uid=%s,offset=%d", uid, offset))
		return false, err
	}
	log.Println(fmt.Printf("SignByRedis CompensateSign success offset=%d,key=%s", offset, key))
	defer redisApi.Close()
	return true, nil
}

// SignInfo 获取{MM}月份前{day}天签到信息
// BITFIELD botgo:u:sign:{uid}:{yyyyMM} get u{day} 0
func (c SignByRedis) SignInfo(uid string) string {
	redisApi := GetRedis()
	defer redisApi.Close()

	log.Println("SignByRedis SignCount")

	result := "\n" + dto.Line +"\n"
	var keys string = buildSignKey(uid)
	var day int = time.Now().Local().Day()
	var dddd string = fmt.Sprintf("u%d", day)

	st, _ := redisApi.Do("BITFIELD", keys, "GET", dddd, 0).Result()
	f := st.([]interface{})
	var v int64 = f[0].(int64)
	log.Println("SignByRedis v ", v)
	for i := day; i > 0; i-- {
		var pos int = (day - i) * -1
		var keys = time.Now().Local().AddDate(0, 0, pos).Format("01-02")
		var value = v>>1<<1 != v

		var tips string
		if value {
			tips  = "✅"
		} else {
			tips  = "❌"
		}
		result += keys + " ----------> " + tips + "\n"
		v >>= 1
	}
	result += dto.Line + "\n"
	return result
}

// 构建key
func buildSignKey(uid string) string {
	nowDate := time.Now().Format("2006-01")
	return fmt.Sprintf("botgo:u:sign:%s:%s", uid, nowDate)
}
